package com.cinema.dao.impl;

import com.cinema.dao.TicketDao;
import com.cinema.model.Ticket;
import com.cinema.util.SimpleFileUtil;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 票务数据访问实现类
 */
public class TicketDaoImpl implements TicketDao {
    private static final String TICKET_DATA_FILE = "tickets.txt";
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private List<Ticket> tickets;

    public TicketDaoImpl() {
        loadTickets();
    }

    private void loadTickets() {
        tickets = new ArrayList<>();
        List<String> lines = SimpleFileUtil.readLines(TICKET_DATA_FILE);
        for (String line : lines) {
            if (line.trim().isEmpty()) continue;
            Ticket ticket = parseTicketFromLine(line);
            if (ticket != null) {
                tickets.add(ticket);
            }
        }
    }

    private void saveTickets() {
        List<String> lines = new ArrayList<>();
        for (Ticket ticket : tickets) {
            lines.add(ticketToLine(ticket));
        }
        SimpleFileUtil.writeLines(TICKET_DATA_FILE, lines);
    }

    private Ticket parseTicketFromLine(String line) {
        try {
            String[] parts = line.split("\\|");
            if (parts.length >= 5) {
                Ticket ticket = new Ticket();
                ticket.setTicketId(parts[0]);
                ticket.setScheduleId(parts[1]);
                // Parse seat position "row-col"
                String[] seatParts = parts[2].split("-");
                if (seatParts.length == 2) {
                    ticket.setSeatRow(Integer.parseInt(seatParts[0]));
                    ticket.setSeatCol(Integer.parseInt(seatParts[1]));
                }
                ticket.setPurchaseTime(LocalDateTime.parse(parts[3], DATE_FORMATTER));
                ticket.setRefunded(Boolean.parseBoolean(parts[4]));
                return ticket;
            }
        } catch (Exception e) {
            // 跳过无效行
        }
        return null;
    }

    private String ticketToLine(Ticket ticket) {
        return ticket.getTicketId() + "|" + 
               ticket.getScheduleId() + "|" + 
               ticket.getSeatRow() + "-" + ticket.getSeatCol() + "|" + 
               ticket.getPurchaseTime().format(DATE_FORMATTER) + "|" + 
               ticket.isRefunded();
    }

    @Override
    public boolean save(Ticket ticket) {
        if (ticket == null || existsById(ticket.getTicketId())) {
            return false;
        }
        
        tickets.add(ticket);
        saveTickets();
        return true;
    }

    @Override
    public Optional<Ticket> findById(String ticketId) {
        return tickets.stream()
                .filter(ticket -> ticketId.equals(ticket.getTicketId()))
                .findFirst();
    }

    @Override
    public List<Ticket> findAll() {
        return new ArrayList<>(tickets);
    }

    @Override
    public List<Ticket> findByScheduleId(String scheduleId) {
        return tickets.stream()
                .filter(ticket -> scheduleId.equals(ticket.getScheduleId()))
                .collect(Collectors.toList());
    }

    @Override
    public List<Ticket> findByDateRange(LocalDateTime startDate, LocalDateTime endDate) {
        return tickets.stream()
                .filter(ticket -> {
                    LocalDateTime purchaseTime = ticket.getPurchaseTime();
                    return !purchaseTime.isBefore(startDate) && !purchaseTime.isAfter(endDate);
                })
                .collect(Collectors.toList());
    }

    @Override
    public List<Ticket> findNonRefundedTickets() {
        return tickets.stream()
                .filter(ticket -> !ticket.isRefunded())
                .collect(Collectors.toList());
    }

    @Override
    public List<Ticket> findRefundedTickets() {
        return tickets.stream()
                .filter(Ticket::isRefunded)
                .collect(Collectors.toList());
    }

    @Override
    public boolean update(Ticket ticket) {
        if (ticket == null) {
            return false;
        }
        
        for (int i = 0; i < tickets.size(); i++) {
            if (ticket.getTicketId().equals(tickets.get(i).getTicketId())) {
                tickets.set(i, ticket);
                saveTickets();
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean deleteById(String ticketId) {
        boolean removed = tickets.removeIf(ticket -> ticketId.equals(ticket.getTicketId()));
        if (removed) {
            saveTickets();
        }
        return removed;
    }

    @Override
    public boolean existsById(String ticketId) {
        return tickets.stream()
                .anyMatch(ticket -> ticketId.equals(ticket.getTicketId()));
    }
}